package org.sunnyleaf.votedemo.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.sunnyleaf.votedemo.Utils;
import org.sunnyleaf.votedemo.client.GreetingService;
import org.sunnyleaf.votedemo.client.Votedemo;
import org.sunnyleaf.votedemo.client.data.*;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {

	public String greetServer(String input) {
		String serverInfo = getServletContext().getServerInfo();
		String userAgent = getThreadLocalRequest().getHeader("User-Agent");
		return "Hello, " + input + "!<br><br>I am running " + serverInfo + ".<br><br>It looks like you are using:<br>" + userAgent;
	}

	@SuppressWarnings("unchecked")
	public LoginResponse checkLogin() {
		LoginResponse lr = new LoginResponse();
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		if (user != null) {
			lr.setLoggedIn(true);
			lr.setNickName(user.getNickname());
			lr.setEmail(user.getEmail());
			lr.setLogoutURL(userService.createLogoutURL("/"));

			PersistenceManager pm = PMF.get().getPersistenceManager();
			try {
				// 找出该用户参加的投票
				Query q = pm.newQuery(VoteRecord.class, "account == '" + user.getEmail() + "'");
				List<VoteRecord> qr = (List<VoteRecord>) q.execute();
				
				List<Vote> pvs = new ArrayList<Vote>();
				List<Boolean> pbs = new ArrayList<Boolean>();
				if (qr.size() == 0) {
					lr.setParticipatedVotes(pvs);
				} else {
					q = pm.newQuery(Vote.class, "id == voteid1");
					q.declareParameters("Long voteid1");
					for (VoteRecord vr : qr) {
						Vote v = DataControler.getVoteByID(vr.getVoteId());
						if( v!= null ){
							List<VoteItem> items  = (List<VoteItem>)DataControler.getAllVoteItems( v.getId() );
							v.setVoteItems( items );
							pvs.add(v);
							pbs.add(vr.isVoted());							
						}
					}
					
					lr.setParticipatedVotes(pvs);
					lr.setVotedFlag(pbs);
				}
				// 找出该用户发起的投票
				q = pm.newQuery(Vote.class, "owner==ownerEmail");
				q.declareParameters("String ownerEmail");
				List<Vote> t1 = (List<Vote>) q.execute(user.getEmail());
				List<Vote> pvs2 = new ArrayList<Vote>();

				for (Vote v : t1) {
					List<VoteItem> items  = (List<VoteItem>)DataControler.getAllVoteItems( v.getId() );
					v.setVoteItems( items );
					pvs2.add(v);
				}
				lr.setOwnedVotes(pvs2);

			} finally {
				pm.close();
			}
			return lr;
			// return
			// "ok"+user.getNickname()+"<"+user.getEmail()+">"+"<a href='"+userService.createLogoutURL("/")+"'>登出</a>";
		} else {
			lr.setLoggedIn(false);
			lr.setLoginURL(userService.createLoginURL("/"));
			return lr;
			// return userService.createLoginURL("/");

		}
	}

	
	public Vote addNewVote(NewVoteRequest nvr){
		PersistenceManager pm = PMF.get().getPersistenceManager();
		boolean bParticipated = false;
		try{
			// save vote and voteitems
			this.saveVote(nvr.getVote());
			Long voteId = nvr.getVote().getId();
			
			// save VoteRecrods
			// save VoteRecordIndex
			StringReader sr = new StringReader( nvr.getRecipients() );
			BufferedReader reader = new BufferedReader(sr);
			int numParticipate= 0;
			List<String> participants = new ArrayList<String>();
			while( true ){
				String account = new String();
				try {
					account = reader.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if(  account == null )
					break;
				
				numParticipate++;
				participants.add( account );
				if( nvr.getVote().getOwner().equals(account ) )
					bParticipated = true;
				
				VoteRecord record = new VoteRecord( account, voteId );
				pm.makePersistent(record);
				Long voteRecordId = record.getId();
				String sha1 = Utils.sha1( account + String.valueOf( voteRecordId ) + Votedemo.SEC_TOKEN );
				VoteRecordIndex recordIndex = new VoteRecordIndex( sha1, voteRecordId );
				pm.makePersistent( recordIndex );
			}
			
			nvr.getVote().setVoteParticipants( participants );
			nvr.getVote().setTotalCount(numParticipate);
			pm.makePersistent( nvr.getVote() );
		}
		finally {
	         pm.close();
	    }	
		
		nvr.getVote().setIsParticipated(bParticipated);
		return nvr.getVote();
	}
	
	/**
	* @gwt.typeArgs <org.sunnyleaf.votedemo.client.data.Vote>
	*/
	public List<Vote> getVotesOwnsTo( String owner ){
		List<Vote> res = (List<Vote>) DataControler.getVotesOwnTo(owner);
		for( Vote vote : res ){
			List<VoteItem> voteItems = (List<VoteItem>)DataControler.getAllVoteItems(vote.getId());
			vote.setVoteItems(voteItems);
		}
		return res;
	}
	
	/**
	* @gwt.typeArgs <org.sunnyleaf.votedemo.client.data.VoteRecord>
	*/
	public List<VoteRecord> getVoteRecords(Long voteId ){
		return DataControler.getVoteRecrods(voteId );
	}
	/**
	* @gwt.typeArgs <org.sunnyleaf.votedemo.client.data.VoteRecord>
	*/	
	public List<VoteItem> getVoteItems(Long voteId){
		return DataControler.getAllVoteItems(voteId);
	}
	
	public Vote getVoteByID( Long id ){
		return DataControler.getVoteByID(id);
	}
	
	public String deleteVoteByID( Long id ){
		// 将Vote删除，并将所有与之相关的数据删除
		List<VoteItem> items = DataControler.getAllVoteItems(id);
		for( VoteItem item: items ){
			DataControler.deleteObjByID( VoteItem.class, item.getId() );
		
		}
		List<VoteRecord> voterecords = DataControler.getVoteRecrods(id);
		for( VoteRecord record:voterecords ){
			String indexSha1 = Utils.sha1( record.getAccount()+record.getId().toString()+Votedemo.SEC_TOKEN );
			DataControler.deleteObjByID(VoteRecordIndex.class, indexSha1 );
			DataControler.deleteObjByID(VoteRecord.class, record.getId());
		}
		
		DataControler.deleteObjByID( Vote.class, id);
		return "delete vote";
	}
	
//	public String saveObj(Object obj ){
//		DataControler.saveObj(obj);
//		return "save obj:"+obj.getClass().getName();
//	}
	
	public String saveVote( Vote vote ){
		// save vote and its vote items
		DataControler.saveObj(vote);	
		if( vote.getVoteItems() != null ){
			for( VoteItem voteItem : vote.getVoteItems() ){
				voteItem.setVoteID( vote.getId() );
				DataControler.saveObj( voteItem );
			}
		}
		
		return "save vote:"+vote.getVoteName();
	}

	@SuppressWarnings("unchecked")
	public VoteRecord getVoteRecord( Long voteId, String account ){
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query q = pm.newQuery( VoteRecord.class );
		q.setFilter( "voteId == voteid && account == userEmail" );
		q.declareParameters("Long voteid,String userEmail");
		List<VoteRecord> res = (List<VoteRecord>)q.execute( voteId, account );
		assert( res.size() == 1 );
		return res.get(0);
	}

	@Override
	public VoteItem getVoteItemByID(Long id) {
		VoteItem res = (VoteItem)DataControler.getObjectById(VoteItem.class, id );
		List<String> itemArray = res.getItemArray();
		List<Integer> countsArray = res.getCountsArray();
		// 必须把类中的Collection复制一遍，不然会丢失，原因不明
		res.setItemArray(new ArrayList<String>());
		res.setCountsArray(new ArrayList<Integer>());
		for( String s:itemArray ){
			res.addItem(s);
		}
		int index = 0;
		for( Integer i:countsArray ){
			res.setItemCount(index++, i);
		}
		return res;
	}

	@Override
	public String saveVoteRecord(VoteRecord record) {
		DataControler.saveObj(record);
		return "";
	}

	@Override
	public List<Vote> getVotesAttendedBy(String user) {
		List<Vote> res = (List<Vote>) DataControler.getVotesAttendedBy(user);
		for( Vote vote : res ){
			List<VoteItem> voteItems = (List<VoteItem>)DataControler.getAllVoteItems(vote.getId());
			vote.setVoteItems(voteItems);
		}
		return res;
	}
	
}
